package main

import (
	"fmt"
)

// defer语句
/*
	defer会将其后面跟随的语句进行延迟处理
	在defer归属的函数即将返回时，将延迟处理的语句按defer定义的逆序进行执行
	先被defer的语句最后被执行，后被defer的语句最先被执行

	defer在命名返回值(操作之后的值)和匿名返回值(操作之前的值)函数中表现不一样
	1. 一般函数的return执行顺序：返回值赋值 -> RET指令
	2. 带defer函数的return执行顺序：返回值赋值 -> 运行defer -> RET指令
	函数内的defer后面需要跟匿名函数

	defer注册要延迟执行的函数时该函数的所有参数都需要先确定其值


*/

// 匿名返回值
func f1() int {
	var a int
	defer func() {
		a++
	}()
	return a
}

// 命名返回值
func f2() (a int) {
	defer func() {
		a++
	}()
	return a
}

func f3() (b int) {
	var a = 0
	defer func() {
		a++
	}()
	return a
}

func calc(index string, a, b int) int {
	ret := a + b
	fmt.Println(index, a, b, ret)
	return ret
}

func main() {
	// // 由上至下 1,2,3
	// fmt.Println("开始")
	// fmt.Println("1")
	// fmt.Println("2")
	// fmt.Println("3")
	// fmt.Println("结束")

	// // defer延迟 2,3,1
	// fmt.Println("开始")
	// defer fmt.Println("1")
	// fmt.Println("2")
	// defer fmt.Println("3")
	// fmt.Println("结束")

	// fmt.Println(f1())
	// fmt.Println(f2())
	// fmt.Println(f3())

	x := 1
	y := 2
	defer calc("AA", x, calc("A", x, y))
	x = 10
	defer calc("BB", x, calc("B", x, y))
	y = 20
}
